package com.kakarote.examine.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.kakarote.core.feign.admin.entity.AdminCompany;
import com.kakarote.core.feign.admin.service.AdminService;
import com.kakarote.core.servlet.BaseServiceImpl;
import com.kakarote.core.utils.UserCacheUtil;
import com.kakarote.examine.constant.*;
import com.kakarote.examine.entity.PO.*;
import com.kakarote.examine.entity.VO.ExamineRecordLogVO;
import com.kakarote.examine.entity.VO.ExamineReturnFlowVO;
import com.kakarote.examine.mapper.ExamineRecordLogMapper;
import com.kakarote.examine.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 审核日志表 服务实现类
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-11-19
 */
@Service
public class ExamineRecordLogServiceImpl extends BaseServiceImpl<ExamineRecordLogMapper, ExamineRecordLog> implements IExamineRecordLogService {

    @Autowired
    private IExamineFlowFinalService examineFlowFinalService;

    @Autowired
    private AdminService adminService;

    @Autowired
    private IExamineFlowService examineFlowService;

    @Autowired
    private IExamineRecordService examineRecordService;

    @Autowired
    private IExamineRecordHistoryLogService examineRecordHistoryLogService;

    /**
     * 查询当前审批层级是否还有其他同级审批未处理
     *
     * @param batchId 批次ID
     * @param sort    当前排序
     * @return num
     */
    @Override
    public ExamineRecordLog queryNextExamineRecordLog(String batchId, Integer sort, Long logId) {
        LambdaQueryChainWrapper<ExamineRecordLog> queryChainWrapper = lambdaQuery().eq(ExamineRecordLog::getBatchId, batchId);
        /*
         查询待审核或者审核中的
         */
        queryChainWrapper.in(ExamineRecordLog::getExamineStatus, ExamineStatusEnum.UNDERWAY.getStatus(), ExamineStatusEnum.AWAIT.getStatus());
        if (sort != null) {
            queryChainWrapper.gt(ExamineRecordLog::getSort, sort);
        }
        //排除自身
        queryChainWrapper.ne(ExamineRecordLog::getLogId, logId);
        return queryChainWrapper.one();
    }


    @Override
    public List<ExamineReturnFlowVO> queryRecordFlowLog(Long recordId, Boolean isIgnoreCopy) {

        ExamineRecord record = examineRecordService.lambdaQuery().eq(ExamineRecord::getRecordId, recordId)
                .last(" limit 1").one();

        ExamineFlow examineFlow = examineFlowService.lambdaQuery().eq(ExamineFlow::getExamineId, record.getExamineId())
                .last(" limit 1").one();

        //获取审批节点名称
        Map<Long, String> flowName = examineFlowService.lambdaQuery().eq(ExamineFlow::getBatchId, examineFlow.getBatchId())
                .notIn(ExamineFlow::getExamineType, ListUtil.toList(ExamineTypeEnum.CONDITION.getType()))
                .list().stream().collect(Collectors.toMap(ExamineFlow::getFlowId, ExamineFlow::getName));
        List<Integer> list = new ArrayList<>();
        list.add(ExamineStatusEnum.UNDERWAY.getStatus());
        list.add(ExamineStatusEnum.AWAIT.getStatus());
        if (isIgnoreCopy) {
            list.add(ExamineStatusEnum.COPY.getStatus());
        }

        //当前审批节点id
        List<Long> currentFlowIds = this.lambdaQuery().eq(ExamineRecordLog::getRecordId, recordId).in(ExamineRecordLog::getExamineStatus, list)
                .orderByAsc(ExamineRecordLog::getLogId).list().stream().map(ExamineRecordLog::getFlowId).collect(Collectors.toList());

        //当前业务审批最终流程
        List<ExamineFlowFinal> examineFlowFinals = examineFlowFinalService.lambdaQuery().eq(ExamineFlowFinal::getRecordId, recordId).orderByAsc(ExamineFlowFinal::getCreateTime)
                .list();
        //只保留审批存在的节点，并添加节点名称
        List<ExamineReturnFlowVO> flowVOList = examineFlowFinals.stream().filter(Objects::nonNull).filter(o -> !currentFlowIds.contains(o.getFlowId())).filter(o -> flowName.containsKey(o.getFlowId())).map(o -> ExamineReturnFlowVO.builder().flowId(o.getFlowId()).name(flowName.get(o.getFlowId())).build())
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ExamineReturnFlowVO::getFlowId))), ArrayList::new));

        flowVOList.add(0, ExamineReturnFlowVO.builder().flowId(null).name("发起点").build());

        return flowVOList;
    }


    @Override
    public List<ExamineRecordLogVO> queryExamineRecordLog(Long recordId, String ownerUserId, Long typeId) {
        List<ExamineRecordLogVO> examineRecordAllLogVoS = new LinkedList<>();

        //查询有效审批历史数据
        List<Integer> statusList = ListUtil.toList(ExamineStatusEnum.AWAIT.getStatus(), ExamineStatusEnum.REMOVE.getStatus(),
                ExamineStatusEnum.UN_SUBMITTED.getStatus());
        //缓存人员名称 减少查询
        Map<Long, String> map = new HashMap<>(16);

        List<ExamineRecordHistoryLog> list = examineRecordHistoryLogService.lambdaQuery()
                .eq(ExamineRecordHistoryLog::getTypeId, typeId)
                .and(i -> i.ne(ExamineRecordHistoryLog::getPassFlag, PassFlagEnum.SKIP_ADMIN_HANDLE.getType()).or().isNull(ExamineRecordHistoryLog::getPassFlag))
                .notIn(ExamineRecordHistoryLog::getExamineStatus, statusList)
                .list();

        Map<Long, List<ExamineRecordHistoryLog>> historyLog = list.stream().collect(Collectors.groupingBy(ExamineRecordHistoryLog::getRecordId));

        for (Long key : historyLog.keySet()) {
            if (key.equals(recordId)) {
                continue;
            }
            List<ExamineRecordLogVO> examineRecordHistoryLogVoS = new ArrayList<>();
            List<ExamineRecordHistoryLog> examineRecordHistoryLogs = historyLog.get(key);
            List<ExamineRecordLog> recordLogs = JSON.parseArray(JSON.toJSONString(examineRecordHistoryLogs), ExamineRecordLog.class);
            disposeLogs(examineRecordHistoryLogVoS, recordLogs, map, key);
            examineRecordAllLogVoS.addAll(examineRecordHistoryLogVoS);
        }

        List<ExamineRecordLog> examineRecordLogs = lambdaQuery()
                .eq(ExamineRecordLog::getRecordId, recordId)
                .notIn(ExamineRecordLog::getExamineStatus, statusList)
                .and(i -> i.ne(ExamineRecordLog::getPassFlag, PassFlagEnum.SKIP_ADMIN_HANDLE.getType()).or().isNull(ExamineRecordLog::getPassFlag))
                .list();
        List<ExamineRecordLogVO> examineRecordLogVoS = new ArrayList<>();

        disposeLogs(examineRecordLogVoS, examineRecordLogs, map, recordId);

        examineRecordAllLogVoS.addAll(examineRecordLogVoS);

        //按照时间和recordId排序
        examineRecordAllLogVoS = examineRecordAllLogVoS.stream().sorted(Comparator.comparing(ExamineRecordLogVO::getExamineTime).thenComparing(ExamineRecordLogVO::getRecordId)).collect(Collectors.toList());
        return examineRecordAllLogVoS;
    }

    public void disposeLogs(List<ExamineRecordLogVO> examineRecordLogVoS, List<ExamineRecordLog> examineRecordLogs, Map<Long, String> map, Long recordId) {

        //查询流程信息
        List<ExamineFlowFinal> examineFlowFinalList = examineFlowFinalService.lambdaQuery().eq(ExamineFlowFinal::getRecordId, recordId).orderByAsc(ExamineFlowFinal::getSort).list();
        //查询待办征求他人意见节点信息

        Map<Long, ExamineFlowFinal> flowMap = examineFlowFinalList.stream().filter(item -> ExamineFlowFlagEnum.SEEK.getType().equals(item.getFlowFlag())).collect(Collectors.toMap(ExamineFlowFinal::getFlowId, Function.identity()));

        ExamineRecordLogVO recordLogVO = new ExamineRecordLogVO();
        for (ExamineRecordLog examineRecordLog : examineRecordLogs) {
            ExamineRecordLogVO examineRecordLogV0 = new ExamineRecordLogVO();
            BeanUtil.copyProperties(examineRecordLog, examineRecordLogV0);
            examineRecordLogV0.setExamineTime(examineRecordLog.getExamineTime());
            if (StrUtil.isNotBlank(examineRecordLog.getExamineReason())) {
                examineRecordLogV0.setExamineReason(examineRecordLog.getExamineReason());
            }
            if (ExamineStatusEnum.CREATE.getStatus().equals(examineRecordLog.getExamineStatus())) {
                Long createUserId = examineRecordLog.getCreateUserId();
                if (map.containsKey(createUserId)) {
                    examineRecordLogV0.setExamineUserName(map.get(createUserId));
                } else {
                    String userName = UserCacheUtil.getUserName(createUserId);
                    examineRecordLogV0.setExamineUserName(userName);
                    map.put(createUserId, userName);
                }
                //记录创建人信息
                recordLogVO = examineRecordLogV0;
                recordLogVO.setExamineTime(examineRecordLogV0.getCreateTime());
            } else {
                Long examineUserId;
                if (ExamineStatusEnum.RESTORE.getStatus().equals(examineRecordLog.getExamineStatus())) {
                    //针对当前审批恢复
                    examineUserId = examineRecordLog.getCreateUserId();
                } else {
                    examineUserId = examineRecordLog.getExamineUserId();
                }
                examineRecordLogV0.setUpdateUserName(UserCacheUtil.getUserName(examineRecordLog.getUpdateUserId()));
                //补充外部审批人
                if (ObjectUtil.isNotEmpty(examineRecordLog.getExamineUserEmail())) {
                    examineRecordLogV0.setExamineUserName(examineRecordLog.getExamineUserEmail());
                } else {
                    if (map.containsKey(examineUserId)) {
                        examineRecordLogV0.setExamineUserName(map.get(examineUserId));
                    } else {
                        String userName = UserCacheUtil.getUserName(examineUserId);
                        examineRecordLogV0.setExamineUserName(userName);
                        map.put(examineUserId, userName);
                    }
                }
                if (flowMap.containsKey(examineRecordLog.getFlowId())) {
                    ExamineFlowFinal examineFlow = flowMap.get(examineRecordLog.getFlowId());
                    if (ExamineFlowInsertFlagEnum.BEFORE.getType().equals(examineFlow.getInsertFlag())) {
                        //如果当前节点是征求意见节点，且在当前节点之前征求则插入一个临时节点用于页面展示
                        ExamineRecordLogVO seekRecordLog = BeanUtil.copyProperties(examineRecordLogV0, ExamineRecordLogVO.class);
                        seekRecordLog.setRemarks(examineFlow.getInsertRemark());
                        //添加征求他人意见节点
                        seekRecordLog.setFlowId(examineFlow.getInsertTarget());
                        seekRecordLog.setExamineUserId(examineFlow.getCreateUserId());
                        String userName = UserCacheUtil.getUserName(examineFlow.getCreateUserId());
                        seekRecordLog.setExamineUserName(userName);
                        seekRecordLog.setExamineStatus(ExamineStatusEnum.SEEK.getStatus());
                        examineRecordLogVoS.add(seekRecordLog);
                    } else {
                        List<ExamineRecordLogVO> recordLogVOs = examineRecordLogVoS.stream()
                                .filter(item -> item.getFlowId().equals(examineFlow.getInsertTarget()))
                                .filter(item -> ObjectUtil.isNotEmpty(item.getCreateTime()))
                                .sorted(Comparator.comparing(ExamineRecordLogVO::getCreateTime).reversed())
                                .collect(Collectors.toList());
                        if (CollectionUtil.isNotEmpty(recordLogVOs)) {
                            ExamineRecordLogVO recordLogVo = CollectionUtil.getFirst(recordLogVOs);
                            recordLogVo.setRemarks(examineFlow.getInsertRemark());
                        }
                    }
                }
                examineRecordLogVoS.add(examineRecordLogV0);
            }
        }
        examineRecordLogVoS.add(0, recordLogVO);
    }



}
